﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.Json.Nodes;
using System.Threading.Tasks;
using DocumentFormat.OpenXml.Bibliography;
using DocumentFormat.OpenXml.Drawing;
using DocumentFormat.OpenXml.Math;
using DocumentFormat.OpenXml.Wordprocessing;
using Magicodes.ExporterAndImporter.Excel;
using Mapster;
using Microsoft.Extensions.Configuration;
using Newtonsoft.Json;
using NP.BPMReportPlatform.DBHelper;
using NP.BPMReportPlatform.Entities.BPM_Business;
using NP.BPMReportPlatform.Entities.BPM_Platform;
using NP.BPMReportPlatform.FrameOrder.Dto;
using NP.BPMReportPlatform.HR.Dto;
using NP.BPMReportPlatform.RecurringJobs;
using NP.BPMReportPlatform.RecurringJobs.Dto;
using NP.Enterprise.Utils.Http;
using SqlSugar;
using Volo.Abp.Application.Dtos;
using Serilog;
using System.Text;
using NP.BPMReportPlatform.BPMPlatform;
using NP.BPMReportPlatform.Utils;
using NP.BPMReportPlatform.Common;

namespace NP.BPMReportPlatform.HR
{
    public class HRAppService : BPMReportPlatformAppService, IHRAppService
    {
        private readonly IConfiguration _configuration;
        private readonly SqlSugarClient _dbBusiness, _dbPlatform;
        private readonly IExcelImporter _importer;
        private readonly ISFSyncJob _sFSyncJob;
        private readonly INPRestHttpHelper _httpClient;
        private ILogger _logger;
        private readonly IBPMPlatformAppService _iBPMPlatformApp;
        private readonly IBPMUtilsAppService _bPMUtilsApp;
        private readonly ICommonService _commonService;

        public HRAppService(IConfiguration configuration, ISqlSugarAppService sqlSugarAppService, IExcelImporter importer, ISFSyncJob sFSyncJob,
            INPRestHttpHelper httpClient, ILogger logger, IBPMPlatformAppService iBPMPlatformApp, IBPMUtilsAppService bPMUtilsApp, ICommonService commonService)
        {
            _configuration = configuration;
            _dbBusiness = sqlSugarAppService.GetBusinessInstance();
            _dbPlatform = sqlSugarAppService.GetPlatformInstance();
            _importer = importer;
            _sFSyncJob = sFSyncJob;
            _httpClient = httpClient;
            _logger = logger;
            _iBPMPlatformApp = iBPMPlatformApp;
            _bPMUtilsApp = bPMUtilsApp;
            _commonService = commonService;
        }
        #region BPM审批配置维护
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<GetApproveConfigOutput>> GetAllAsync(GetApproveConfigInput input)
        {
            RefAsync<int> totalCount = 0;
            var listViewDto = await _dbBusiness.Queryable<HRProcessApprovalConfiguration>()
                    .WhereIF(!string.IsNullOrWhiteSpace(input.ProcessName), x => x.ProcessName == input.ProcessName)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Rank), x => x.Rank == input.Rank)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.CatalogName), x => x.CatalogName == input.CatalogName)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.ReportingLine), x => x.ReportingLine == input.ReportingLine)
               .ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            var mapperList = ObjectMapper.Map<List<HRProcessApprovalConfiguration>, List<GetApproveConfigOutput>>(listViewDto);
            foreach (var item in mapperList)
            {
                item.Approver1 = GetApproverNameByCode(item.Approver1);
                item.Approver2 = GetApproverNameByCode(item.Approver2);
                item.Approver3 = GetApproverNameByCode(item.Approver3);
                item.Approver4 = GetApproverNameByCode(item.Approver4);
                item.Approver5 = GetApproverNameByCode(item.Approver5);
                item.Approver6 = GetApproverNameByCode(item.Approver6);
                item.Approver7 = GetApproverNameByCode(item.Approver7);
                item.ReportingLine = GetApproverNameByCode(item.ReportingLine);
            }
            //返回结果
            return new PagedResultDto<GetApproveConfigOutput>()
            {
                TotalCount = totalCount,
                Items = mapperList
            };
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>

        public async Task<List<GetApproveConfigOutput>> ExportAsync(GetApproveConfigInput input)
        {
            //var listViewDto = await GetQueryable(input);
            var listViewDto = await _dbBusiness.Queryable<HRProcessApprovalConfiguration>()
                    .WhereIF(!string.IsNullOrWhiteSpace(input.ProcessName), x => x.ProcessName == input.ProcessName)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Rank), x => x.Rank.Contains(input.Rank))
                    .WhereIF(!string.IsNullOrWhiteSpace(input.CatalogName), x => x.CatalogName == input.CatalogName)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.ReportingLine), x => x.ReportingLine == input.ReportingLine)
               .ToListAsync();

            var mapperList = ObjectMapper.Map<List<HRProcessApprovalConfiguration>, List<GetApproveConfigOutput>>(listViewDto);
            foreach (var item in mapperList)
            {
                item.Approver1 = GetApproverNameByCode(item.Approver1);
                item.Approver2 = GetApproverNameByCode(item.Approver2);
                item.Approver3 = GetApproverNameByCode(item.Approver3);
                item.Approver4 = GetApproverNameByCode(item.Approver4);
                item.Approver5 = GetApproverNameByCode(item.Approver5);
                item.Approver6 = GetApproverNameByCode(item.Approver6);
                item.Approver7 = GetApproverNameByCode(item.Approver7);
                item.ReportingLine = GetApproverNameByCode(item.ReportingLine);
            }
            return mapperList;
        }


        /// <summary>
        /// 导入Excel
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public async Task<ImportResultExt<ImportApproveConfigInput>> ImporterExcel(byte[] bytes, string operationType)
        {
            Stream stream = new MemoryStream(bytes);
            var rst = await _importer.Import<ImportApproveConfigInput>(stream);
            var importData = rst.Data;
            if (!rst.HasError)
            {
                //int index = 1;
                List<HRProcessApprovalConfiguration> list = new List<HRProcessApprovalConfiguration>();
                // 获取基础连带数据
                foreach (var item in importData)
                {
                    HRProcessApprovalConfiguration HRProcessApprovalConfiguration = new HRProcessApprovalConfiguration()
                    {
                        Id = Guid.NewGuid(),
                        ProcessName = item.ProcessName,
                        Rank = item.Rank,
                        CatalogName = item.CatalogName,
                        Approver1 = GetApproverCodeByName(item.Approver1),
                        Approver2 = GetApproverCodeByName(item.Approver2),
                        Approver3 = GetApproverCodeByName(item.Approver3),
                        Approver4 = GetApproverCodeByName(item.Approver4),
                        Approver5 = GetApproverCodeByName(item.Approver5),
                        Approver6 = GetApproverCodeByName(item.Approver6),
                        Approver7 = GetApproverCodeByName(item.Approver7),
                        ReportingLine = GetApproverCodeByName(item.ReportingLine)
                    };

                    list.Add(HRProcessApprovalConfiguration);
                }
                if (operationType == "add")
                {
                    await _dbBusiness.Insertable(list).ExecuteCommandAsync();
                }
                else if (operationType == "update")
                {
                    await _dbBusiness.Updateable(list).ExecuteCommandAsync();
                }


            }
            var resp = new ImportResultExt<ImportApproveConfigInput>()
            {
                Data = importData,
                Exception = rst.Exception,
                RowErrors = rst.RowErrors,
                TemplateErrors = rst.TemplateErrors
            };
            return resp;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task SaveAsync(SaveApproveConfigInput input)
        {
            var mapperInput = ObjectMapper.Map<SaveApproveConfigInput, HRProcessApprovalConfiguration>(input);
            mapperInput.Id = Guid.NewGuid();
            mapperInput.Approver1 = GetApproverCodeByName(mapperInput.Approver1) ?? "";
            mapperInput.Approver2 = GetApproverCodeByName(mapperInput.Approver2) ?? "";
            mapperInput.Approver3 = GetApproverCodeByName(mapperInput.Approver3) ?? "";
            mapperInput.Approver4 = GetApproverCodeByName(mapperInput.Approver4) ?? "";
            mapperInput.Approver5 = GetApproverCodeByName(mapperInput.Approver5) ?? "";
            mapperInput.Approver6 = GetApproverCodeByName(mapperInput.Approver6) ?? "";
            mapperInput.Approver7 = GetApproverCodeByName(mapperInput.Approver7) ?? "";
            mapperInput.ReportingLine = GetApproverCodeByName(mapperInput.ReportingLine) ?? "";
            await _dbBusiness.Insertable(mapperInput).ExecuteCommandAsync();
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task EditAsync(SaveApproveConfigInput input)
        {
            try
            {
                var mapperInput = ObjectMapper.Map<SaveApproveConfigInput, HRProcessApprovalConfiguration>(input);
                mapperInput.Approver1 = GetApproverCodeByName(mapperInput.Approver1) ?? "";
                mapperInput.Approver2 = GetApproverCodeByName(mapperInput.Approver2) ?? "";
                mapperInput.Approver3 = GetApproverCodeByName(mapperInput.Approver3) ?? "";
                mapperInput.Approver4 = GetApproverCodeByName(mapperInput.Approver4) ?? "";
                mapperInput.Approver5 = GetApproverCodeByName(mapperInput.Approver5) ?? "";
                mapperInput.Approver6 = GetApproverCodeByName(mapperInput.Approver6) ?? "";
                mapperInput.Approver7 = GetApproverCodeByName(mapperInput.Approver7) ?? "";
                mapperInput.ReportingLine = GetApproverCodeByName(mapperInput.ReportingLine) ?? "";
                await _dbBusiness.Updateable(mapperInput).ExecuteCommandAsync();
            }
            catch (Exception e)
            {
                throw e;
            }

        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteAsync(Guid id)
        {
            var cnt = await _dbBusiness.Deleteable<HRProcessApprovalConfiguration>().Where(x => (x.Id == id)).ExecuteCommandAsync();
        }

        /// <summary>
        /// 根据员工工号获取审批信息
        /// </summary>
        /// <param name="workNumber"></param>
        public async Task<List<UserFetch2Dto>> GetHREmployeeApprover(string workNumber)
        {
            List<UserFetch2Dto> userFetch2Dtos = new List<UserFetch2Dto>();
            var rank = "";// 职级
            var catalogName = "";// 归属分类
            var userData = _sFSyncJob.GetCommonRoleUser(workNumber);
            var userExtension = await _dbPlatform.Queryable<UserExtension>().FirstAsync(x => x.Sapemployeeid == workNumber);
            if (userData.Count > 0)
            {
                catalogName = userData.Find(x => x.RoleCode == "cust_organizationCategory").UserName;//归属分类
                rank = userData.Find(x => x.RoleCode == "Posnc")?.WorkNumber;//职级
                var hRPA = _dbBusiness.Queryable<HRProcessApprovalConfiguration>().Where(x => x.ProcessName == "离职" && x.Rank.ToUpper() == rank.ToUpper() && x.CatalogName == catalogName).First();
                var hRPA_ALl = _dbBusiness.Queryable<HRProcessApprovalConfiguration>().Where(x => x.ProcessName == "离职" && x.Rank.ToUpper() == rank.ToUpper() && x.CatalogName == "/").First();
                if (hRPA != null)
                {
                    userFetch2Dtos = GetHRUserApprover(workNumber, hRPA, userData);
                }
                else if (hRPA_ALl != null)
                {
                    userFetch2Dtos = GetHRUserApprover(workNumber, hRPA_ALl, userData);
                }

                // 职级O系列，排除钟总
                var posnc = userExtension?.Posnc;
                if (!string.IsNullOrEmpty(posnc) && posnc.ToUpper().Contains("O"))
                {
                    userFetch2Dtos = userFetch2Dtos.Where(x => x.WorkNumber != "00051849")
                        .OrderBy(x => x.Sort).ToList();
                    var index = 1;
                    foreach(var userFetchDto in userFetch2Dtos)
                    {
                        userFetchDto.Sort = index;
                        index++;
                    }
                }

                var keyPostData = await _dbPlatform.Queryable<UserExtension>().Where(x => x.Sapemployeeid == workNumber && x.KEYPOST == "是").Select(x => x.KEYPOST).FirstAsync();
                if (!string.IsNullOrWhiteSpace(keyPostData))
                {
                    userFetch2Dtos.Add(new UserFetch2Dto()
                    {
                        RoleCode = "KeyPost",
                        RoleName = "关键岗位",
                        Sort = 99,
                        WorkNumber = workNumber
                    });
                }
            }
            return userFetch2Dtos;
        }

        /// <summary>
        /// 根据员工号获取员工利益审批人
        /// </summary>
        /// <param name="workNumber"></param>
        /// <returns></returns>
        public List<UserFetchDto> GetEmployeeBenefitsApprover(string workNumber)
        {
            var userData = _sFSyncJob.GetCommonRoleUser(workNumber);

            userData ??= new List<UserFetchDto>();

            var dto1 = new UserFetchDto
            {
                RoleCode = "FourthLevelSupervisor",
                RoleName = "四级主管",
                WorkNumber = "",
                UserName = "",
            };
            var dto2 = new UserFetchDto
            {
                RoleCode = "FifthLevelSupervisor",
                RoleName = "五级主管",
                WorkNumber = "",
                UserName = "",
            };
            var dto3 = new UserFetchDto
            {
                RoleCode = "OrganizationCategory",
                RoleName = "组织类别",
                WorkNumber = "其他",
                UserName = "其他",
            };
            var dto4 = new UserFetchDto
            {
                RoleCode = "FactoryManagerWorkNumber",
                RoleName = "厂长工号",
                WorkNumber = "",
                UserName = "",
            };

            var directorOfSuperDirector = userData.FirstOrDefault(x => x.RoleCode == "DirectorOfSuperDirector");
            if (directorOfSuperDirector != null)
            {
                var directorOfDirectorOfSuperDirector =
                    _dbPlatform.Queryable<UserExtension, UserExtension>((a, b) => a.Sapemployeeid == b.Bossemployeeid)
                    .Where((a, b) => b.Sapemployeeid == directorOfSuperDirector.WorkNumber).Select((a, b) => a).First();
                if (directorOfDirectorOfSuperDirector != null)
                {
                    dto1.WorkNumber = directorOfDirectorOfSuperDirector.Sapemployeeid;
                    dto1.UserName = directorOfDirectorOfSuperDirector.Name;

                    var directorOfDirectorOfDirectorOfSuperDirector =
                        _dbPlatform.Queryable<UserExtension, UserExtension>((a, b) => a.Sapemployeeid == b.Bossemployeeid)
                        .Where((a, b) => b.Sapemployeeid == directorOfDirectorOfSuperDirector.Sapemployeeid).Select((a, b) => a).First();
                    if (directorOfDirectorOfDirectorOfSuperDirector != null)
                    {
                        dto2.WorkNumber = directorOfDirectorOfDirectorOfSuperDirector.Sapemployeeid;
                        dto2.UserName = directorOfDirectorOfDirectorOfSuperDirector.Name;
                    }
                }
            }

            var user = _dbPlatform.Queryable<Users>().First(x => x.WorkNumber == workNumber);
            if (user != null && !string.IsNullOrEmpty(user.FullPathCode))
            {
                var codes = user.FullPathCode.Split("_").ToList();
                if (codes.Any())
                {
                    var dic = _dbBusiness.Queryable<KeyValues>().Where(x => x.ParentCode == "EmployeeBenefitsOrgApprover" &&
                        codes.Contains(x.Code)).First();
                    if (dic != null)
                    {
                        dto3.WorkNumber = dic.Name;
                        dto3.UserName = dic.Name;
                        dto4.WorkNumber = dic.Remark ?? "";
                        dto4.UserName = string.IsNullOrEmpty(dic.Remark) ? "" :
                            _dbPlatform.Queryable<Users>().First(x => x.WorkNumber == dic.Remark)?.UserName ?? "";
                    }
                }
            }

            userData.Add(dto1);
            userData.Add(dto2);
            userData.Add(dto3);
            userData.Add(dto4);

            return userData;

        }
        private List<UserFetch2Dto> GetHRUserApprover(string workNumber, HRProcessApprovalConfiguration hRPA, List<UserFetchDto> userData)
        {
            List<UserFetch2Dto> userFetch2Dtos = new List<UserFetch2Dto>();
            if (hRPA != null)
            {
                var hRPA1 = hRPA;
                int i = 1;
                var reportingLine_workNumber = "";
                var reportingLine = userData.Find(x => x.RoleCode == hRPA.ReportingLine);
                reportingLine_workNumber = reportingLine?.WorkNumber;
                var roleCode1 = hRPA.Approver1 == "president CEO DOA" ? "CEO DOA" : hRPA.Approver1;
                var approver1 = userData.Find(x => x.RoleCode == roleCode1);
                if (approver1 != null)
                {
                    UserFetch2Dto userDto = new UserFetch2Dto() { RoleName = GetApproverNameByCode(hRPA.Approver1), RoleCode = approver1.RoleCode, UserName = approver1.UserName, WorkNumber = approver1.WorkNumber, Sort = i };
                    userFetch2Dtos.Add(userDto);
                    i++;
                }
                var roleCode2 = hRPA.Approver2 == "president CEO DOA" ? "CEO DOA" : hRPA.Approver2;
                var approver2 = userData.Find(x => x.RoleCode == roleCode2);
                if (approver2 != null)
                {
                    UserFetch2Dto userDto = new UserFetch2Dto() { RoleName = GetApproverNameByCode(hRPA.Approver2), RoleCode = approver2.RoleCode, UserName = approver2.UserName, WorkNumber = approver2.WorkNumber, Sort = i };
                    userFetch2Dtos.Add(userDto);
                    i++;
                }
                var roleCode3 = hRPA.Approver3 == "president CEO DOA" ? "CEO DOA" : hRPA.Approver3;
                var approver3 = userData.Find(x => x.RoleCode == roleCode3);
                if (approver3 != null)
                {
                    UserFetch2Dto userDto = new UserFetch2Dto() { RoleName = GetApproverNameByCode(hRPA.Approver3), RoleCode = approver3.RoleCode, UserName = approver3.UserName, WorkNumber = approver3.WorkNumber, Sort = i };
                    userFetch2Dtos.Add(userDto);
                    i++;
                }
                var roleCode4 = hRPA.Approver4 == "president CEO DOA" ? "CEO DOA" : hRPA.Approver4;
                var approver4 = userData.Find(x => x.RoleCode == roleCode4);
                if (approver4 != null)
                {
                    UserFetch2Dto userDto = new UserFetch2Dto() { RoleName = GetApproverNameByCode(hRPA.Approver4), RoleCode = approver4.RoleCode, UserName = approver4.UserName, WorkNumber = approver4.WorkNumber, Sort = i };
                    userFetch2Dtos.Add(userDto);
                    i++;
                }
                var roleCode5 = hRPA.Approver5 == "president CEO DOA" ? "CEO DOA" : hRPA.Approver5;
                var approver5 = userData.Find(x => x.RoleCode == roleCode5);
                if (approver5 != null)
                {
                    UserFetch2Dto userDto = new UserFetch2Dto() { RoleName = GetApproverNameByCode(hRPA.Approver5), RoleCode = approver5.RoleCode, UserName = approver5.UserName, WorkNumber = approver5.WorkNumber, Sort = i };
                    userFetch2Dtos.Add(userDto);
                    i++;
                }
                var roleCode6 = hRPA.Approver6 == "president CEO DOA" ? "CEO DOA" : hRPA.Approver6;
                var approver6 = userData.Find(x => x.RoleCode == roleCode6);
                if (approver6 != null)
                {
                    UserFetch2Dto userDto = new UserFetch2Dto() { RoleName = GetApproverNameByCode(hRPA.Approver6), RoleCode = approver6.RoleCode, UserName = approver6.UserName, WorkNumber = approver6.WorkNumber, Sort = i };
                    userFetch2Dtos.Add(userDto);
                    i++;
                }
                var roleCode7 = hRPA.Approver7 == "president CEO DOA" ? "CEO DOA" : hRPA.Approver7;
                var approver7 = userData.Find(x => x.RoleCode == roleCode7);
                if (approver7 != null)
                {
                    UserFetch2Dto userDto = new UserFetch2Dto() { RoleName = GetApproverNameByCode(hRPA.Approver7), RoleCode = approver7.RoleCode, UserName = approver7.UserName, WorkNumber = approver7.WorkNumber, Sort = i };
                    userFetch2Dtos.Add(userDto);
                    i++;
                }
                // 直接上级 如果跟汇报线封顶里面的审批节点审批人是同一个人  隔级主管就不用传
                var zjsjWorkNumber = userFetch2Dtos.Find(u => u.RoleCode == "Director")?.WorkNumber;
                var gjzg = userFetch2Dtos.Find(u => u.RoleCode == "SuperDirector");
                if (reportingLine_workNumber == zjsjWorkNumber)
                {
                    userFetch2Dtos.Remove(gjzg);
                }
            }
            //特殊处理人员  直接上级是钟中林（00051849）的话 就替换成许松兴（00000056）
            if (workNumber == "00007500" || workNumber == "00001727" || workNumber == "00002218" || workNumber == "00008472"
                || workNumber == "00025499" || workNumber == "00025722" || workNumber == "00026006" || workNumber == "00029650"
                || workNumber == "00052583" || workNumber == "00036646" || workNumber == "00023368")
            {
                foreach (var item in userFetch2Dtos)
                {
                    if (item.RoleCode == "Director" && item.WorkNumber == "00051849")
                    {
                        item.WorkNumber = "00000056";
                        item.UserName = "许松兴";
                    }
                }
            }

            return userFetch2Dtos;
        }

        private string GetApproverNameByCode(string code)
        {
            return _dbPlatform.Queryable<Dictionaries>().Where(x => x.TypeCode == "HrCommonRoleDataConfig" &&
                x.Value == code).Select(x => x.Name).First() ?? code;
        }

        private string GetApproverCodeByName(string name)
        {
            return _dbPlatform.Queryable<Dictionaries>().Where(x => x.TypeCode == "HrCommonRoleDataConfig" &&
                x.Name == name).Select(x => x.Value).First() ?? name;
        }

        /// <summary>
        /// 根据UserId,relationshipType从SFOtherApproveEntity获取RelUserId
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="relationshipType"></param>
        /// <returns></returns>
        public async Task<List<GetSFOtherApproveRelOutput>> GetSFOtherApproveRelUserId(string userId)
        {
            var rst = await _dbPlatform.Queryable<SFOtherApproverEntity>()
                .Where(x => x.UserId.Equals(userId) && SqlFunc.ContainsArray(new string[] { "1938", "2160" }, x.RelationshipType))
                .Select(x => new GetSFOtherApproveRelOutput() { EmployeeCode = x.RelUserId, RelationshipType = x.RelationshipType }).ToListAsync();
            return rst;
        }

        /// <summary>
        /// 根据工号获取UserExtension Region数据
        /// </summary>
        /// <param name="sapEmployeeId"></param>
        /// <returns></returns>
        public async Task<GetUserRegionOutput> GetUserRegionInfo(string sapEmployeeId)
        {
            return (await _dbPlatform.Queryable<UserExtension>().Where(x => x.Sapemployeeid.Equals(sapEmployeeId))
               .Select(x => new GetUserRegionOutput
               {
                   RegionCode = x.RegionCode,
                   RegionName = x.RegionName,
               }).FirstAsync()) ?? new GetUserRegionOutput();
        }



        #endregion

        #region 手机费额度配置维护
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<GetPhoneFeeLimitConfigOutput>> GetAllAsync(GetPhoneFeeLimitConfigInput input)
        {

            RefAsync<int> totalCount = 0;
            var listViewDto = await _dbBusiness.Queryable<PhoneFeeLimitConfig>()
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Type), x => x.Type == input.Type)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Rank), x => x.Rank == input.Rank)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.RankName), x => x.RankName == input.RankName)
                    //.Where(x => Convert.ToDateTime(x.ExpiryDateStart) <= DateTime.Now && Convert.ToDateTime(x.ExpiryDateEnd) >= DateTime.Now)
               .ToPageListAsync(input.PageIndex, input.PageSize, totalCount);

            var mapperList = ObjectMapper.Map<List<PhoneFeeLimitConfig>, List<GetPhoneFeeLimitConfigOutput>>(listViewDto);
            //返回结果
            return new PagedResultDto<GetPhoneFeeLimitConfigOutput>()
            {
                TotalCount = totalCount,
                Items = mapperList
            };
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>

        public async Task<List<GetPhoneFeeLimitConfigOutput>> ExportAsync(GetPhoneFeeLimitConfigInput input)
        {
            //var listViewDto = await GetQueryable(input);
            var listViewDto = await _dbBusiness.Queryable<PhoneFeeLimitConfig>()
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Type), x => x.Type == input.Type)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Rank), x => x.Rank == input.Rank)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.RankName), x => x.RankName == input.RankName)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Limit), x => x.RankName == input.Limit)
               .ToListAsync();

            var mapperList = ObjectMapper.Map<List<PhoneFeeLimitConfig>, List<GetPhoneFeeLimitConfigOutput>>(listViewDto);
            return mapperList;
        }


        /// <summary>
        /// 导入Excel
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public async Task<ImportResultExt<ImportPhoneFeeLimitConfigInput>> ImporterPhoneFeeLimitExcel(byte[] bytes, string operationType)
        {
            Stream stream = new MemoryStream(bytes);
            var rst = await _importer.Import<ImportPhoneFeeLimitConfigInput>(stream);
            var importData = rst.Data;
            if (!rst.HasError)
            {
                //int index = 1;
                List<PhoneFeeLimitConfig> list = new List<PhoneFeeLimitConfig>();
                // 获取基础连带数据
                foreach (var item in importData)
                {
                    PhoneFeeLimitConfig PhoneFeeLimitConfig = new PhoneFeeLimitConfig()
                    {
                        Id = Guid.NewGuid(),
                        Type = item.Type,
                        Rank = item.Rank,
                        RankName = item.RankName,
                        Limit = item.Limit,
                        ExpiryDateStart = Convert.ToDateTime(item.ExpiryDateStart).ToString("yyyy/MM/dd"),
                        ExpiryDateEnd = Convert.ToDateTime(item.ExpiryDateEnd).ToString("yyyy/MM/dd"),
                        Remark = item.Remark,
                    };

                    list.Add(PhoneFeeLimitConfig);
                }
                if (operationType == "add")
                {
                    await _dbBusiness.Insertable(list).ExecuteCommandAsync();
                }
                else if (operationType == "update")
                {
                    await _dbBusiness.Updateable(list).ExecuteCommandAsync();
                }


            }
            var resp = new ImportResultExt<ImportPhoneFeeLimitConfigInput>()
            {
                Data = importData,
                Exception = rst.Exception,
                RowErrors = rst.RowErrors,
                TemplateErrors = rst.TemplateErrors
            };
            return resp;
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task SaveAsync(SavePhoneFeeLimitConfigInput input)
        {
            var currentData = await _dbBusiness.Queryable<PhoneFeeLimitConfig>()
                .WhereIF(string.IsNullOrWhiteSpace(input.RankName), x =>string.IsNullOrWhiteSpace(x.RankName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.RankName), x=>x.RankName==input.RankName)
                .Where(x => x.Type == input.Type && x.Rank == input.Rank &&
                ((Convert.ToDateTime(x.ExpiryDateEnd)>= Convert.ToDateTime(input.ExpiryDateStart) && Convert.ToDateTime(x.ExpiryDateEnd) <= Convert.ToDateTime(input.ExpiryDateEnd)) ||
                (Convert.ToDateTime(x.ExpiryDateStart) >= Convert.ToDateTime(input.ExpiryDateStart) && Convert.ToDateTime(x.ExpiryDateStart) <= Convert.ToDateTime(input.ExpiryDateEnd)))
                ).ToListAsync();
            if (currentData.Any())
            {
                throw new Exception("当前手机额度配置日期有重叠");
            }
            PhoneFeeLimitConfig mapperInput = new PhoneFeeLimitConfig()
            {
                Id = Guid.NewGuid(),
                Type = input.Type,
                Rank = input.Rank,
                RankName = input.RankName,
                Limit = input.Limit,
                ExpiryDateStart = input.ExpiryDateStart,
                ExpiryDateEnd = input.ExpiryDateEnd,
                Remark = input.Remark
            };
            await _dbBusiness.Insertable(mapperInput).ExecuteCommandAsync();
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task EditAsync(SavePhoneFeeLimitConfigInput input)
        {
            try
            {
                var currentData = await _dbBusiness.Queryable<PhoneFeeLimitConfig>()
                 .WhereIF(string.IsNullOrWhiteSpace(input.RankName), x => string.IsNullOrWhiteSpace(x.RankName))
                 .WhereIF(!string.IsNullOrWhiteSpace(input.RankName), x => x.RankName == input.RankName)
                 .Where(x => x.Id!=input.Id && x.Type == input.Type && x.Rank == input.Rank &&
                 ((Convert.ToDateTime(x.ExpiryDateEnd) >= Convert.ToDateTime(input.ExpiryDateStart) && Convert.ToDateTime(x.ExpiryDateEnd) <= Convert.ToDateTime(input.ExpiryDateEnd)) ||
                 (Convert.ToDateTime(x.ExpiryDateStart) >= Convert.ToDateTime(input.ExpiryDateStart) && Convert.ToDateTime(x.ExpiryDateStart) <= Convert.ToDateTime(input.ExpiryDateEnd)))
                 ).ToListAsync();
                if (currentData.Any())
                {
                    throw new Exception("当前手机额度配置日期有重叠");
                }
                var mapperInput = ObjectMapper.Map<SavePhoneFeeLimitConfigInput, PhoneFeeLimitConfig>(input);

                await _dbBusiness.Deleteable<PhoneFeeLimitConfig>().Where(x => (x.Id == mapperInput.Id)).ExecuteCommandAsync();
                await _dbBusiness.Insertable(mapperInput).ExecuteCommandAsync();
            }
            catch (Exception e)
            {
                throw e;
            }

        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeletePhoneFeeLimitConfigAsync(Guid id)
        {
            try
            {
                var cnt = await _dbBusiness.Deleteable<PhoneFeeLimitConfig>().Where(x => (x.Id == id)).ExecuteCommandAsync();
            }
            catch (Exception e)
            {

                throw new Exception(e.Message);
            }
            
        }
        /// <summary>
        /// 查询手机费额度 
        /// </summary>
        /// <returns></returns>
        public async Task<List<UserLimitDto>> GetPhoneFeeLimitConfigInfo()
        {
            return await _dbBusiness.Queryable<PhoneFeeLimit>()
               .Select(x => new UserLimitDto
               {
                   WorkNumber = x.WorkNumber,
                   Limit = x.Limit
               }).ToListAsync();
        }

        /// <summary>
        /// 获取用户数据权限
        /// </summary>
        /// <returns></returns>
        public async Task<List<string>> GetUserDataPermissions(string EmployeeCode)
        {
            List<string> worknumbers = new List<string>();

            // 权限过滤
            var deptcodes = await _dbPlatform.Queryable<SFPositionUserRelEntity, SFApproverEntity>((a, b) => a.PositionCode == b.PositionCode)
                .Where((a, b) => a.UserId == EmployeeCode && b.RoleCode == "HRBPPermission").Select((a, b) => b.DeptCode).ToListAsync();

            if (deptcodes != null && deptcodes.Count() > 0)
            {
                worknumbers = await _dbPlatform.Queryable<UserExtension>().Where(t => deptcodes.Contains(t.Objid_1) || deptcodes.Contains(t.Objid_2)
                || deptcodes.Contains(t.Objid_3) || deptcodes.Contains(t.Objid_4) || deptcodes.Contains(t.Objid_5) || deptcodes.Contains(t.Objid_6)
                || deptcodes.Contains(t.Objid_7) || deptcodes.Contains(t.Objid_8))
                    .Select(t => t.Sapemployeeid).ToListAsync();
            }

            return worknumbers;
        }

        /// <summary>
        /// 获取用户数据权限,提供给ESB接口
        /// </summary>
        /// <returns></returns>
        public async Task<List<string>> GetUserDataPermissionsForDept(string EmployeeCode)
        {
            List<string> worknumbers = new List<string>();

            // 权限过滤
            var deptcodes = await _dbPlatform.Queryable<SFPositionUserRelEntity, SFApproverEntity>((a, b) => a.PositionCode == b.PositionCode)
                .Where((a, b) => a.UserId == EmployeeCode && b.RoleCode == "HRBPPermission").Select((a, b) => b.DeptCode).Distinct().ToListAsync();

            return deptcodes;
        }

        ///// <summary>
        ///// 自动更新手机费额度表数据
        ///// </summary>
        ///// <returns></returns>
        //public async Task<List<PhoneFeeLimit>> AutoUpdatePhoneFeeLimit()
        //{
        //    List<PhoneFeeLimit> phoneFeeLimits = new List<PhoneFeeLimit>();

        //    //获取立邦所有用户
        //    var users = await _dbPlatform.Queryable<Users, UserExtension>((a, b) => a.WorkNumber == b.Sapemployeeid)
        //       .Where((a, b) => a.Status == 1 && b.Status == "3")
        //       .Select((a, b) => new UserExtensionDto()
        //       {
        //           Sapemployeeid = b.Sapemployeeid,
        //           Dutyname = b.Dutyname,
        //           Employeepostname =b.Employeepostname,
        //           Sapcompanycode = b.Sapcompanycode,
        //           Poste =b.Poste,
        //           Posnc=b.Posnc
        //       }).Distinct().ToListAsync();
        //    var now = DateTime.Now;
        //    //查询手机费额度配置信息
        //    var phoneFeeLimitConfigData = await _dbBusiness.Queryable<PhoneFeeLimitConfig>()
        //        .Where(x=> Convert.ToDateTime(x.ExpiryDateStart)< now && Convert.ToDateTime(x.ExpiryDateEnd)>now)
        //        .ToListAsync();
        //    foreach (var item in users)
        //    {
        //        PhoneFeeLimit phoneFeeLimit = new PhoneFeeLimit();
        //        phoneFeeLimit.WorkNumber = item.Sapemployeeid;
        //        // 直接销售属于销售类，其它属于职能类
        //        if (item.Dutyname == "直接销售")
        //        {
        //            var limit = phoneFeeLimitConfigData.Find(x => x.Type == "销售类" && x.Rank == item.Posnc)?.Limit;
        //            phoneFeeLimit.Limit = limit.IsNullOrEmpty() ? "0" : limit;
        //        }
        //        else
        //        {
        //            if(item.Posnc== "O12")
        //            {
        //                var limit = phoneFeeLimitConfigData.Find(x => x.Type == "职能类" && x.Rank == item.Posnc && x.RankName==item.Employeepostname)?.Limit;
        //                phoneFeeLimit.Limit = limit.IsNullOrEmpty() ? "0" : limit;
        //            }
        //            else
        //            {
        //                var limit = phoneFeeLimitConfigData.Find(x => x.Type == "职能类" && x.Rank == item.Posnc)?.Limit;
        //                phoneFeeLimit.Limit = limit.IsNullOrEmpty()?"0":limit;
        //            }
        //        }
        //        var specialLimit = SpecialUserLimit(phoneFeeLimitConfigData, item);
        //        if (!specialLimit.IsNullOrEmpty())
        //        {
        //            phoneFeeLimit.Limit = specialLimit;
        //        }
        //        phoneFeeLimits.Add(phoneFeeLimit);
        //    }
        //    return phoneFeeLimits;
        //}
        //private string SpecialUserLimit(List<PhoneFeeLimitConfig> phoneFeeLimitConfigData, UserExtensionDto userExtension)
        //{
        //    string limit = null;
        //    var companycodeList = phoneFeeLimitConfigData.Where(x => x.Type == "公司" ).Select(x=>x.Rank).ToList();
        //    if (SqlFunc.ContainsArray<string>(companycodeList.ToArray(), userExtension.Sapcompanycode)){
        //        limit = "0";
        //    }
        //    var specialUser = phoneFeeLimitConfigData.Find(x => x.Type == "特殊设置" && x.Rank==userExtension.Sapemployeeid);
        //    if (specialUser != null)
        //    {
        //        limit = specialUser.Limit;
        //    }
        //    return limit;
        //}
        #endregion

        #region 交通费额度配置维护
        /// <summary>
        /// 查询
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task<PagedResultDto<GetTrafficFeeLimitConfigOutput>> GetAllAsync(GetTrafficFeeLimitConfigInput input)
        {

            RefAsync<int> totalCount = 0;
            var listViewDto = await _dbBusiness.Queryable<TrafficFeeLimitConfig>()
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Type), x => x.Type == input.Type)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Category1), x => x.Category1.Contains(input.Category1))
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Category2), x => x.Category2.Contains(input.Category2))
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Category3), x => x.Category3.Contains(input.Category3))
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Category4), x => x.Category4.Contains(input.Category4))
               .ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            var mapperList=listViewDto.Adapt<List<GetTrafficFeeLimitConfigOutput>>();
             
            //返回结果
            return new PagedResultDto<GetTrafficFeeLimitConfigOutput>()
            {
                TotalCount = totalCount,
                Items = mapperList
            };
        }
        /// <summary>
        /// 导出
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>

        public async Task<List<GetTrafficFeeLimitConfigOutput>> ExportAsync(GetTrafficFeeLimitConfigInput input)
        {
            var listViewDto = await _dbBusiness.Queryable<TrafficFeeLimitConfig>()
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Type), x => x.Type == input.Type)
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Category1), x => x.Category1.Contains(input.Category1))
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Category2), x => x.Category2.Contains(input.Category2))
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Category3), x => x.Category3.Contains(input.Category3))
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Category4), x => x.Category4.Contains(input.Category4))
                    .WhereIF(!string.IsNullOrWhiteSpace(input.Limit), x => x.Limit == input.Limit)
               .ToListAsync();
            var mapperList = listViewDto.Adapt<List<GetTrafficFeeLimitConfigOutput>>();
            return mapperList;
        }

        /// <summary>
        /// 导入Excel
        /// </summary>
        /// <param name="bytes"></param>
        /// <returns></returns>
        public async Task<ImportResultExt<ImportTrafficFeeLimitConfigInput>> ImporterTrafficFeeLimitExcel(byte[] bytes)
        {
            try
            {
                Stream stream = new MemoryStream(bytes);
                var rst = await _importer.Import<ImportTrafficFeeLimitConfigInput>(stream);
                var importData = rst.Data;
                if (!rst.HasError)
                {
                    int index = 1;
                    List<TrafficFeeLimitConfig> list = new List<TrafficFeeLimitConfig>();
                    // 获取基础连带数据
                    foreach (var item in importData)
                    {
                        index++;
                        
                        TrafficFeeLimitConfig trafficFeeLimitConfig = new TrafficFeeLimitConfig()
                        {
                            Id = Guid.NewGuid(),
                            Type = item.Type,
                            Category1 = item.Category1,
                            Category2 = item.Category2,
                            Category3 = item.Category3,
                            Category4 = item.Category4,
                            Limit = item.Limit,
                            ExpiryDateStart = Convert.ToDateTime(item.ExpiryDateStart).ToString("yyyy/MM/dd"),
                            ExpiryDateEnd = Convert.ToDateTime(item.ExpiryDateEnd).ToString("yyyy/MM/dd"),
                            Remark = item.Remark,
                        };

                        list.Add(trafficFeeLimitConfig);
                    }
                    _dbBusiness.BeginTran();
                    await _dbBusiness.Deleteable<TrafficFeeLimitConfig>().ExecuteCommandAsync();
                    await _dbBusiness.Insertable(list).ExecuteCommandAsync();
                    _dbBusiness.CommitTran();
                }
                var resp = new ImportResultExt<ImportTrafficFeeLimitConfigInput>()
                {
                    Data = importData,
                    Exception = rst.Exception,
                    RowErrors = rst.RowErrors,
                    TemplateErrors = rst.TemplateErrors
                };
                return resp;
            }
            catch (Exception ex)
            {
                _dbBusiness.RollbackTran();
                throw ex;
            }
        }

        /// <summary>
        /// 新增
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task SaveAsync(SaveTrafficFeeLimitConfigInput input)
        {
            var currentData = await _dbBusiness.Queryable<TrafficFeeLimitConfig>()
                 .WhereIF(!string.IsNullOrWhiteSpace(input.Category2), x => x.Category2 == input.Category2)
                 .WhereIF(!string.IsNullOrWhiteSpace(input.Category3), x => x.Category3 == input.Category3)
                 .WhereIF(!string.IsNullOrWhiteSpace(input.Category4), x => x.Category3 == input.Category4)
                .Where(x => x.Type == input.Type && x.Category1 == input.Category1 &&
                ((Convert.ToDateTime(x.ExpiryDateEnd) >= Convert.ToDateTime(input.ExpiryDateStart) && Convert.ToDateTime(x.ExpiryDateEnd) <= Convert.ToDateTime(input.ExpiryDateEnd)) ||
                (Convert.ToDateTime(x.ExpiryDateStart) >= Convert.ToDateTime(input.ExpiryDateStart) && Convert.ToDateTime(x.ExpiryDateStart) <= Convert.ToDateTime(input.ExpiryDateEnd)))
                ).ToListAsync();
            if (currentData.Any())
            {
                throw new Exception("当前交通费额度配置日期有重叠");
            }
            var mapperInput = input.Adapt<TrafficFeeLimitConfig>();
            mapperInput.Id = Guid.NewGuid();
            await _dbBusiness.Insertable(mapperInput).ExecuteCommandAsync();
        }

        /// <summary>
        /// 编辑
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public async Task EditAsync(SaveTrafficFeeLimitConfigInput input)
        {
            try
            {
                var currentData = await _dbBusiness.Queryable<TrafficFeeLimitConfig>()
                 .WhereIF(!string.IsNullOrWhiteSpace(input.Category2), x => x.Category2 == input.Category2)
                 .WhereIF(!string.IsNullOrWhiteSpace(input.Category3), x => x.Category3 == input.Category3)
                 .WhereIF(!string.IsNullOrWhiteSpace(input.Category4), x => x.Category3 == input.Category4)
                 .Where(x => x.Id != input.Id && x.Type == input.Type && x.Category1 == input.Category1 &&
                 ((Convert.ToDateTime(x.ExpiryDateEnd) >= Convert.ToDateTime(input.ExpiryDateStart) && Convert.ToDateTime(x.ExpiryDateEnd) <= Convert.ToDateTime(input.ExpiryDateEnd)) ||
                 (Convert.ToDateTime(x.ExpiryDateStart) >= Convert.ToDateTime(input.ExpiryDateStart) && Convert.ToDateTime(x.ExpiryDateStart) <= Convert.ToDateTime(input.ExpiryDateEnd)))
                 ).ToListAsync();
                if (currentData.Any())
                {
                    throw new Exception("当前交通费额度配置日期有重叠");
                }
                var mapperInput = input.Adapt<TrafficFeeLimitConfig>();
                await _dbBusiness.Deleteable<TrafficFeeLimitConfig>().Where(x => (x.Id == mapperInput.Id)).ExecuteCommandAsync();
                await _dbBusiness.Insertable(mapperInput).ExecuteCommandAsync();
            }
            catch (Exception e)
            {
                throw e;
            }

        }

        /// <summary>
        /// 一键同步，推送数据到费控
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<string> PushTrafficFeeLimitAsync(Guid id)
        {
            try
            {
                var trafficFeeLimit = await _dbBusiness.Queryable<TrafficFeeLimitConfig>().Where(x => (x.Id == id)).FirstAsync();
                if (trafficFeeLimit == null)
                {
                    return "未查到当前配置，请刷新页面重试！";
                }
                var needSyncData=await GetPushTrafficFeeLimitData(trafficFeeLimit);
                if (needSyncData.Count == 0)
                {
                    return "未找到符合当前配置条件的用户 ！";
                }
                else
                {
                    int batchSize = 200;
                    var mapperInput = needSyncData.Select(x => new TrafficFeePushDataDto()
                    {
                        employee_number = x.WorkNumber,
                        budget_amount = x.Limit,
                        fiscal_date = x.FiscalDate
                    }).ToList();
                    for (int i = 0; i < mapperInput.Count; i+=batchSize)
                    {
                        int remaining = mapperInput.Count - i;
                        int currentBatchSize = Math.Min(remaining, batchSize);
                        var batchs = mapperInput.Skip(i).Take(currentBatchSize).ToList();
                        await SyncTrafficFee(batchs);
                    }
                }
                return "同步成功";
                
            }
            catch (Exception e)
            {
                throw new Exception(e.Message);
            }

        }

        /// <summary>
        /// 删除
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task DeleteTrafficFeeLimitConfigAsync(Guid id)
        {
            try
            {
                var cnt = await _dbBusiness.Deleteable<TrafficFeeLimitConfig>().Where(x => (x.Id == id)).ExecuteCommandAsync();
            }
            catch (Exception e)
            {

                throw new Exception(e.Message);
            }

        }
        /// <summary>
        /// 查询交通费额度 
        /// </summary>
        /// <returns></returns>
        public async Task<List<UserLimitDto>> GetTrafficFeeLimitConfigInfo()
        {
            return await _dbBusiness.Queryable<TrafficFeeLimit>()
               .Select(x => new UserLimitDto
               {
                   WorkNumber = x.WorkNumber,
                   Limit = x.Limit
               }).ToListAsync();
        }
 
        /// <summary>
        /// 推送交通费额度到费控，单次不超过200
        /// </summary>
        /// <param name="dataList"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<string> SyncTrafficFee(List<TrafficFeePushDataDto> dataList)
        {
            try
            {
                if (dataList.Count>200) { return "同步失败！单次推送数据不能超过200，当前数量：" + dataList.Count; }
                string bizId = Guid.NewGuid().ToString();
                string timestamp = ((DateTime.Now.ToUniversalTime().Ticks - 621355968000000000) / 10000000).ToString(); // 同步对应的时间戳
                var tokenheaders = new Dictionary<string, string>
                {
                    {"requestId", Guid.NewGuid().ToString()},
                    {"trackId", Guid.NewGuid().ToString()},
                    {"sourceSystem","BPMNEW"},
                    {"serviceName", "S_XXX_CloudPense_GetToken_S"} // 获取token
                };
                string tokenUrl = _configuration["Nippon:FrameOrder:TokenUrl"];
                var tokenResult = await _httpClient.PostAsync<TokenOutput>(tokenUrl, new TokenInput(), tokenheaders);

                var token = tokenResult.resCode == 200000 ? tokenResult.data.access_token : "";
                var headers = new Dictionary<string, string>
                {
                    {"requestId", Guid.NewGuid().ToString()},
                    {"trackId", Guid.NewGuid().ToString()},
                    {"sourceSystem","BPMNEW"},
                    {"serviceName", "S_XXX_CloudPense_budgetSynchronization_S"},
                    { "accessToken", token}
                };
                var temp = new
                {
                    bizId = bizId,
                    timestamp = timestamp,
                    data = dataList
                };

                // 等待回调
                var result = await _httpClient.PostAsync<dynamic>(_configuration["Nippon:FrameOrder:ESBNEWERPAPI"], temp, headers);
                if (result.resCode == "200000" && result.resMsg == "success")
                {
                    return "同步成功";
                }
                return "同步失败。报错信息：" + result.resMsg;
            }
            catch (Exception ex)
            {
                throw new Exception("同步失败。报销信息：" + ex.Message);
            }
        }
        private async Task<List<TrafficFeeLimit>> GetPushTrafficFeeLimitData(TrafficFeeLimitConfig input)
        {
            StringBuilder log = new StringBuilder();
            log.AppendLine($"-----GetPushTrafficFeeLimitData方法----");
            log.AppendLine($"入参：{JsonConvert.SerializeObject(input)}");
            List<TrafficFeeLimit> trafficFeeLimits = new List<TrafficFeeLimit>();
            //获取立邦所有用户
            var users = await _dbPlatform.Queryable<Users, UserExtension>((a, b) => a.WorkNumber == b.Sapemployeeid)
               .Where((a, b) => a.Status == 1 && b.Status == "3")
               .Select((a, b) => new UserExtDto()
               {
                   Sapemployeeid = b.Sapemployeeid,
                   FullPathText = a.FullPathText,
                   FullPathCode = a.FullPathCode,
                   Duty = b.Duty,
                   Dutyname = b.Dutyname,
                   Poste = b.Poste,
                   Posnc = b.Posnc
               }).Distinct().ToListAsync();
            var fiscalDate = Convert.ToDateTime(input.ExpiryDateStart);//开始日期
            var currentMM = Convert.ToDateTime(DateTime.Now.AddMonths(1).ToString("yyyy-MM")).AddDays(-1);//当前月最后一天
            if (input.Type == "工号")
            {
                var user = users.Where(x => x.Sapemployeeid == input.Category1).FirstOrDefault();
                if (user != null && fiscalDate <= currentMM)
                {
                    while (fiscalDate<= currentMM)
                    {
                        TrafficFeeLimit trafficFeeLimit = new TrafficFeeLimit();
                        trafficFeeLimit.WorkNumber = input.Category1;
                        trafficFeeLimit.Limit = input.Limit;
                        trafficFeeLimit.FiscalDate = fiscalDate.ToString("yyyy-MM");
                        trafficFeeLimits.Add(trafficFeeLimit);
                        fiscalDate= fiscalDate.AddMonths(1);
                    }
                }
            }
            else
            {
                while (fiscalDate <= currentMM)
                {
                    //查询交通费额度配置信息
                    var trafficFeeLimitConfigData = await _dbBusiness.Queryable<TrafficFeeLimitConfig>()
                    .Where(x => Convert.ToDateTime(x.ExpiryDateStart) <= fiscalDate && Convert.ToDateTime(x.ExpiryDateEnd) >= fiscalDate)
                    .ToListAsync();
                    log.AppendLine($"trafficFeeLimitConfigData：{JsonConvert.SerializeObject(trafficFeeLimitConfigData)}");
                    var trafficFeeLimitConfigData1 = trafficFeeLimitConfigData.Where(x => x.Type == "工号");
                    var trafficFeeLimitConfigData2 = trafficFeeLimitConfigData.Where(x => x.Type == "标准逻辑" && x.Id==input.Id);
                    log.AppendLine($"trafficFeeLimitConfigData2：{JsonConvert.SerializeObject(trafficFeeLimitConfigData2)}");
                    foreach (var item in users)
                    {
                        TrafficFeeLimit trafficFeeLimit = new TrafficFeeLimit();
                        trafficFeeLimit.WorkNumber = item.Sapemployeeid;
                        // 优先级：工号>标准逻辑
                        if (trafficFeeLimitConfigData1.Where(x => x.Category1 == item.Sapemployeeid).Count() > 0)
                        {
                            //按照特殊工号不需处理
                        }
                        else if (trafficFeeLimitConfigData2.Where(x => item.FullPathCode.Contains(x.Category1))
                            .Where(x => x.Category2.IsNullOrEmpty() ? true : x.Category2 == item.Posnc.Substring(0, 1))
                             .Where(x => x.Category3.IsNullOrEmpty() ? true : x.Category3 == item.Dutyname)
                            .Where(x => x.Category4.IsNullOrEmpty() ? true :  x.Category4 == item.Duty)
                             .Count() > 0)
                        {
                            //按照标准逻辑
                            //var currnetConfig = trafficFeeLimitConfigData2.Where(x => item.FullPathCode.Contains(x.Category1))
                            //    .Where(x => x.Category2.IsNullOrEmpty() ? true : x.Category2 == item.Posnc.Substring(0, 1))
                            //    .Where(x => x.Category3.IsNullOrEmpty() ? true : x.Category3 == item.Dutyname)
                            //    .Where(x => x.Category4.IsNullOrEmpty() ? true : x.Category4 == item.Duty).FirstOrDefault();
                            trafficFeeLimit.WorkNumber = item.Sapemployeeid;
                            trafficFeeLimit.Limit = input.Limit;
                            trafficFeeLimit.FiscalDate = fiscalDate.ToString("yyyy-MM");
                            trafficFeeLimits.Add(trafficFeeLimit);
                            trafficFeeLimits.Add(trafficFeeLimit);
                        }
                    }
                    fiscalDate = fiscalDate.AddMonths(1);
                }       
            }
            log.AppendLine($"trafficFeeLimits：{JsonConvert.SerializeObject(trafficFeeLimits)}");
            _logger.Error(log.ToString());
            return trafficFeeLimits;
           
        }
        #endregion


        #region HR费控系统前置审批
        public async Task<PagedResultDto<GetHRFKXTQZSPOutput>> GetAllAsync(GetHRFKXTQZSPInput input)
        {
            RefAsync<int> totalCount = 0;
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToPageListAsync(input.PageIndex, input.PageSize, totalCount);
            var userId = await _iBPMPlatformApp.GetUserAsync(CurrentUser.UserName);
            var instanceNumbers = listQueryable.Select(x => x.InstanceNumber).ToArray();
            var activitieTasks =await _commonService.GetInstancesSteps(instanceNumbers);
            foreach ( var item in listViewDto)
            {
                item.Url = _bPMUtilsApp.GetProcessUrl(item.InstanceNumber, userId);
                item.Approver1 = activitieTasks.Where(x => x.Name == "一级审批").FirstOrDefault()?.UserName;
                item.Approver2 = activitieTasks.Where(x => x.Name == "二级审批").FirstOrDefault()?.UserName;
                item.Approver3 = activitieTasks.Where(x => x.Name == "三级审批").FirstOrDefault()?.UserName;
                item.Approver4 = activitieTasks.Where(x => x.Name == "四级审批").FirstOrDefault()?.UserName;
                item.Approver5 = activitieTasks.Where(x => x.Name == "五级审批").FirstOrDefault()?.UserName;
                item.Approver6 = activitieTasks.Where(x => x.Name == "六级审批").FirstOrDefault()?.UserName;
            }
            //返回结果
            return new PagedResultDto<GetHRFKXTQZSPOutput>()
            {
                TotalCount = totalCount,
                Items = listViewDto
            };
        }

        public async Task<List<GetHRFKXTQZSPOutput>> ExportAsync(GetHRFKXTQZSPInput input)
        {
            var listQueryable = GetQueryable(input);
            var listViewDto = await listQueryable.ToListAsync();
            var instanceNumbers = listQueryable.Select(x => x.InstanceNumber).ToArray();
            var activitieTasks = await _commonService.GetInstancesSteps(instanceNumbers);
            foreach (var item in listViewDto)
            {
                item.Approver1 = activitieTasks.Where(x => x.Name == "一级审批").FirstOrDefault()?.UserName;
                item.Approver2 = activitieTasks.Where(x => x.Name == "二级审批").FirstOrDefault()?.UserName;
                item.Approver3 = activitieTasks.Where(x => x.Name == "三级审批").FirstOrDefault()?.UserName;
                item.Approver4 = activitieTasks.Where(x => x.Name == "四级审批").FirstOrDefault()?.UserName;
                item.Approver5 = activitieTasks.Where(x => x.Name == "五级审批").FirstOrDefault()?.UserName;
                item.Approver6 = activitieTasks.Where(x => x.Name == "六级审批").FirstOrDefault()?.UserName;
            }
            return listViewDto;
        }

        private ISugarQueryable<GetHRFKXTQZSPOutput> GetQueryable(GetHRFKXTQZSPInput input)
        {
            var currentUserId = Guid.Empty;
            if (!input.IsQueryAll)
            {
                var currentUserDto = _dbPlatform.Queryable<Users>()
                    .Where(x => x.WorkNumber.Equals(CurrentUser.UserName)).First();
                if (currentUserDto != null)
                {
                    currentUserId = currentUserDto.UserId;
                }
            }
            var listQueryable = _dbBusiness.Queryable<HRFKXTQZSPHeader, HRFKXTQZSPDetail, BusinessProcessesNew>(
                    (x, m, bu) => new JoinQueryInfos(JoinType.Left, x.InstanceNumber == m.InstanceNumber, JoinType.Left, x.InstanceNumber == bu.InstanceId))
                .WhereIF(!string.IsNullOrWhiteSpace(input.InstanceNumber), (x, m) => x.InstanceNumber.Contains(input.InstanceNumber))
                .WhereIF(!input.IsQueryAll, x => x.AddUserId.Equals(currentUserId))
                .WhereIF(!input.OrderStatus.IsNullOrEmpty(), (x, m, bu) => SqlFunc.ContainsArray<string>(input.OrderStatus.ToArray(), bu.ProcessStatusName))
                .WhereIF(!string.IsNullOrWhiteSpace(input.AddUserName), (x, m, bu) => bu.StartUserName.Equals(input.AddUserName))
                .WhereIF(input.StartCreationTime != null && input.EndCreationTime != null, x => x.AddTime >= input.StartCreationTime && x.AddTime.AddDays(-1) <= input.EndCreationTime)
                 .WhereIF(!string.IsNullOrWhiteSpace(input.Factory), (x, m, bu) => m.Factory.Contains(input.Factory)||m.FactoryName.Contains(input.Factory))
                .Select((x, m, bu) =>
                    new GetHRFKXTQZSPOutput()
                    {
                        InstanceNumber = x.InstanceNumber,
                        CreateTime = x.AddTime,
                        AddUserName = bu.StartUserName,
                        TotalCost = x.TotalCost,
                        SortNo = m.SortNo,
                        Factory = m.Factory,
                        FactoryName = m.FactoryName,
                        CostCode = m.CostCode,
                        CostType=m.CostType,
                        Amount= m.Amount,
                        ApproveDate = bu.FinishTime != null ? bu.FinishTime.Value.ToString("yyyy-MM-dd") : "",
                        OrderStatus = bu.ProcessStatusName,
                    }).MergeTable().Distinct().OrderBy(ins => ins.InstanceNumber, OrderByType.Desc).OrderBy(ins =>ins.SortNo);
            return listQueryable;
        }
        #endregion
    }
}